/**
 * list.cpp
 * \brief: various list handling routines
 * \author: coanor
 * \date: 2010.5.4
 */
#include <stdarg.h>
#include "nodes/op_list.h"
#include "nodes/nodes.h"
#include "print/print.h"

parse_value_t *make_integer(long i)
{
	parse_value_t *v = make_node(parse_value_t);
	v->type = T_integer_t;
	v->val.ival = i;
	return v;
}

parse_value_t *make_float(double d)
{
	parse_value_t *v = make_node(parse_value_t);
	v->type = T_float_t;
	v->val.dval = d;
	return v;
}

parse_value_t *make_string(char *str)
{
	parse_value_t *v = make_node(parse_value_t);
	v->type = T_string_t;
	v->val.str = str;
	return v;
}

list_t *make_list(void *elem, ...)
{
    va_list args;
    list_t *retval = NIL;
    list_t *temp = NIL;
    list_t *tempcons = NIL;

    va_start(args, elem);

        temp = (list_t *)elem;
        while (temp != (void *) -1) {
                temp = lcons(temp, NIL);
                if (tempcons == NIL)
                        retval = temp;
                else
                        lnext(tempcons) = temp;
                tempcons = temp;

                temp = (list_t *)va_arg(args, void *);
        }

    va_end(args);

    return (retval);
}

list_t *lcons(void *datum, list_t *list)
{
    list_t *l = make_node(list_t);
    lfirst(l) = datum;
    lnext(l) = list;
    return l;
}

list_t *nconc(list_t *l1, list_t *l2)
{
    list_t *temp;

    if (l1 == NIL)
        return l2;
    if (l2 == NIL)
        return l1;
    if (l1 == l2)
        elog(WARN, "tryout to nconc a list to itself");

    for (temp = l1; lnext(temp)!=NULL; temp = lnext(temp))
        ;

    lnext(temp) = l2;
    return(l1);      /* list1 is now list1[]list2  */
}

list_t *lappend(list_t *list, void *obj)
{
    return nconc(list, lcons(obj, NIL));
}
